export class Deserializer {
  mapNameClass = new Map<string, any>([])

  register(className: string, ctor: any) {
    this.mapNameClass.set(className, ctor)
    // console.log(`类型"${className}"注册成功`)
  }

  deserialize(obj: any): any {

    // 是Object
    if (Object.prototype.toString.call(obj) === '[object Object]') {
      const cname = obj.className
      let ret = obj
      // 需要进行实例化
      if (cname) {
        const ctor = this.mapNameClass.get(cname)
        console.assert(ctor, `对于类型 "${cname}", 缺失构造函数。是不是在该类的静态初始化块中没有调用？`)
        ret = lodash.assign(new ctor(), obj)
      }
      
      for (const key of Object.keys(ret)) {
        ret[key] = this.deserialize(ret[key])
      }
      return ret
    }
    else if (Object.prototype.toString.call(obj) === '[object Array]') {
      const _obj = obj as any[]
      return _obj.map(x => this.deserialize(x))
    }
    else {
      // 不是Object，直接返回
      return obj
    }
    
  }

  clone<T>(obj: T): T {
    return this.deserialize(lodash.cloneDeep(obj))
  }
}